package cn.lyjuan.dwz_manage.core.config;

import cn.lyjuan.dwz_manage.core.java.cst.DwzManageCst;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jndi.JndiObjectFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by chad on 2016/8/9.
 */
@Configuration
@EnableTransactionManagement
public class DBConfig
{
    /**
     * 测试时无法从 web.xml 下引入 jndi 信息
     *
     * @return
     */
    @Bean(name = "dataSource")
    @Profile(value = {"dev", "qa"})
    public DataSource dataSourceQA(DwzManageCst dwzManageCst)
    {
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName(dwzManageCst.getTestJdbcDriver());
        ds.setUrl(dwzManageCst.getTestJdbcUrl());
        ds.setUsername(dwzManageCst.getTestJdbcUsername());
        ds.setPassword(dwzManageCst.getTestJdbcPassword());

        return ds;
    }

    /**
     * dev时从 META-INF 下加载 jndi
     * prod 是由WEB容器提供
     *
     * @return
     */
    @Bean(name = "dataSource")
    @Profile(value = "prod")
    public JndiObjectFactoryBean dataSourceProd(DwzManageCst dwzManageCst)
    {
        JndiObjectFactoryBean jndiObjectFB = new JndiObjectFactoryBean();
        jndiObjectFB.setJndiName(dwzManageCst.getJndiName());
        jndiObjectFB.setResourceRef(true);
        jndiObjectFB.setProxyInterface(DataSource.class);

        return jndiObjectFB;
    }

    /**
     * MyBatis扫包
     *
     * @return
     */
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(DwzManageCst dwzManageCst)
    {
        String basePackage = "cn.lyjuan.dwz_manage.core.base.mapper" +
                ",cn.lyjuan.dwz_manage.core.java.mapper";

        // 加入第三方包
        String[] thirdPkgs = dwzManageCst.getMapperBasePackages();
        if (null != thirdPkgs && thirdPkgs.length > 0)
        {
            for (String t : thirdPkgs)
                basePackage += "," + t;
        }

        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();

        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
        mapperScannerConfigurer.setBasePackage(basePackage);

        return mapperScannerConfigurer;
    }

    /**
     * 会话
     *
     * @param dataSource
     * @return
     */
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource, DwzManageCst dwzManageCst) throws IOException
    {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();

        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setConfigLocation(new ClassPathResource("/mybatis-config.xml"));

        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

        List<Resource> list = new ArrayList<>(4);
        Resource[]     rs   = resolver.getResources("classpath:cn/lyjuan/dwz_manage/core/base/mapper/*.xml");
        list.addAll(Arrays.asList(rs));
        rs   = resolver.getResources("classpath:cn/lyjuan/dwz_manage/core/java/mapper/*.xml");
        list.addAll(Arrays.asList(rs));

        // 加入第三方包
        String[] thirdPkgs = dwzManageCst.getMapperBasePackages();
        if (null != thirdPkgs && thirdPkgs.length > 0)
        {
            for (String t : thirdPkgs)
            {
                t = "classpath:" + t.replace(".", "/") + "/*.xml";
                rs = resolver.getResources(t);
                list.addAll(Arrays.asList(rs));
            }
        }

        sqlSessionFactoryBean.setMapperLocations(list.toArray(new Resource[list.size()]));

        return sqlSessionFactoryBean;
    }

    /**
     * 开启事务管理
     *
     * @param dataSource
     * @return
     */
    @Bean
    public PlatformTransactionManager transactionManager(DataSource dataSource)
    {
        return new DataSourceTransactionManager(dataSource);
    }
}
